﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using KinSocket;

namespace KinConquer.Entities
{
    public class Entity : IMapObject
    {
        public Byte[] SpawnPacket { get; set; }

        public UInt32 DMap { get; set; }
        public UInt32 Map { get; set; }
        public ObjectType ObjectType { get; private set; }

        public Rect Bounds { get; private set; }
        public event EventHandler BoundsChanged;

        public Entity(ObjectType t)
        {
            this.ObjectType = t;
            this.SpawnPacket = new Byte[221];
            PacketConstructor.Write((UInt16)this.SpawnPacket.Length, 0, SpawnPacket);
            PacketConstructor.Write((UInt16)10014, 2, SpawnPacket);
        }

        public UInt32 Lookface
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 4); }
            set { PacketConstructor.Write(value, 4, SpawnPacket); }
        }
        public UInt32 Identifier
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 8); }
            set { PacketConstructor.Write(value, 8, SpawnPacket); }
        }
        public UInt32 GuildId
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 12); }
            set { PacketConstructor.Write(value, 12, SpawnPacket); }
        }
        public UInt16 GuildRank
        {
            get { return BitConverter.ToUInt16(SpawnPacket, 16); }
            set { PacketConstructor.Write((UInt16)value, 16, SpawnPacket); }
        }
        public StatusFlags StatusFlag
        {
            get { return (StatusFlags)BitConverter.ToUInt64(SpawnPacket, 22); }
            set { PacketConstructor.Write((UInt64)value, 22, SpawnPacket); }
        }

        public StatusFlags2 StatusFlag2
        {
            get { return (StatusFlags2)BitConverter.ToUInt64(SpawnPacket, 30); }
            set { PacketConstructor.Write((UInt64)value, 30, SpawnPacket); }
        }

        public UInt32 Helmet
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 40); }
            set
            {
                PacketConstructor.Write(value, 40, SpawnPacket);
                /*Item i = Equipment.GetPos(Item.Positions.Head);
                if (i != null)
                {
                    PacketConstructor.Write((Byte)i.Color, 109, SpawnPacket);
                }*/
            }
        }

        public UInt32 Garment
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 44); }
            set { PacketConstructor.Write(value, 44, SpawnPacket); }
        }

        public UInt32 Armor
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 48); }
            set
            {
                PacketConstructor.Write(value, 48, SpawnPacket);
                /*Item i = Equipment.GetPos(Item.Positions.Armor);
                if (i != null)
                {
                    PacketConstructor.Write((Byte)i.Color, 123, SpawnPacket);
                }*/
            }
        }

        public UInt32 LeftWeapon
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 52); }
            set
            {
                PacketConstructor.Write(value, 52, SpawnPacket);
                /*Item i = Equipment.GetPos(Item.Positions.Left);
                if (i != null && i.IsItemType(900))
                {
                    PacketConstructor.Write((Byte)i.Color, 107, SpawnPacket);
                }*/
            }
        }

        public UInt32 RightWeapon
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 56); }
            set { PacketConstructor.Write(value, 56, SpawnPacket); }
        }

        public UInt32 LeftAccessory
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 60); }
            set { PacketConstructor.Write(value, 60, SpawnPacket); }
        }

        public UInt32 RightAccessory
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 64); }
            set { PacketConstructor.Write(value, 64, SpawnPacket); }
        }

        public UInt32 Steed
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 68); }
            set
            {
                PacketConstructor.Write(value, 68, SpawnPacket);
                /*Item i = Equipment.GetPos(Item.Positions.Steed);
                if (i != null)
                {
                    PacketConstructor.Write((Byte)i.Plus, 133, SpawnPacket);
                    PacketConstructor.Write((UInt32)i.SocketProgress, 139, SpawnPacket);
                }*/
            }
        }
        public UInt32 SteedArmor
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 72); }
            set { PacketConstructor.Write(value, 72, SpawnPacket); }
        }
        public UInt32 HitPoints
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 80); }
            set { PacketConstructor.Write(value, 80, SpawnPacket); }
        }
        public UInt16 HairStyle
        {
            get { return BitConverter.ToUInt16(SpawnPacket, 84); }
            set { PacketConstructor.Write(value, 84, SpawnPacket); }
        }
        public UInt16 X
        {
            get { return BitConverter.ToUInt16(SpawnPacket, 86); }
            set { PacketConstructor.Write(value, 86, SpawnPacket); }
        }
        public UInt16 Y
        {
            get { return BitConverter.ToUInt16(SpawnPacket, 88); }
            set { PacketConstructor.Write(value, 88, SpawnPacket); }
        }
        public Byte Angle
        {
            get { return SpawnPacket[90]; }
            set { SpawnPacket[90] = (Byte)value; }
        }
        public Byte Action
        {
            get { return SpawnPacket[91]; }
            set { SpawnPacket[91] = (Byte)value; }
        }
        public Byte Reborn
        {
            get { return SpawnPacket[98]; }
            set { SpawnPacket[98] = value; }
        }
        public Byte Level
        {
            get { return SpawnPacket[99]; }
            set { SpawnPacket[99] = value; }
        }

        public Boolean Away
        {
            get { return Convert.ToBoolean(this.SpawnPacket[102]); }
            set { this.SpawnPacket[102] = Convert.ToByte(value); }
        }

        public Byte NobilityRank
        {
            get { return SpawnPacket[119]; }
            set { SpawnPacket[119] = (Byte)value; }
        }
        public UInt32 ClanId
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 155); }
            set { PacketConstructor.Write((UInt32)value, 155, SpawnPacket); }
        }
        public Byte ClanRank
        {
            get { return SpawnPacket[159]; }
            set { SpawnPacket[159] = (Byte)value; }
        }
        public UInt16 Title
        {
            get { return BitConverter.ToUInt16(SpawnPacket, 167); }
            set { PacketConstructor.Write(value, 167, SpawnPacket); }
        }

        public UInt32 DragonSoulHead
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 182); }
            set { PacketConstructor.Write(value, 182, SpawnPacket); }
        }
        public UInt32 DragonSoulArmor
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 186); }
            set { PacketConstructor.Write(value, 186, SpawnPacket); }
        }
        public UInt32 DragonSoulLeft
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 190); }
            set { PacketConstructor.Write(value, 190, SpawnPacket); }
        }
        public UInt32 DragonSoulRight
        {
            get { return BitConverter.ToUInt32(SpawnPacket, 194); }
            set { PacketConstructor.Write(value, 194, SpawnPacket); }
        }
        public Byte Class
        {
            get
            {
                switch (Reborn)
                {
                    case 0: return FirstClass;
                    case 1: return SecondClass;
                    case 2: return ThirdClass;
                }
                return FirstClass;
            }
            set
            {
                switch (Reborn)
                {
                    case 0: FirstClass = value; break;
                    case 1: SecondClass = value; break;
                    case 2: ThirdClass = value; break;
                }
            }
        }
        public Byte ThirdClass
        {
            get { return SpawnPacket[207]; }
            set { SpawnPacket[207] = value; }
        }
        public Byte SecondClass
        {
            get { return SpawnPacket[209]; }
            set { SpawnPacket[209] = value; }
        }
        public Byte FirstClass
        {
            get { return SpawnPacket[211]; }
            set { SpawnPacket[211] = value; }
        }

        public String Name
        {
            get { return Encoding.ASCII.GetString(SpawnPacket, 220, SpawnPacket[219]); }
            set
            {
                PacketConstructor.Write(4, 218, SpawnPacket);
                PacketConstructor.Write(value, 219, SpawnPacket);
            }
        }

        public String ClanName
        {
            get { return Encoding.ASCII.GetString(SpawnPacket, 222 + SpawnPacket[219], SpawnPacket[221 + SpawnPacket[219]]); }
            set
            {
                Byte[] tmp = new Byte[SpawnPacket.Length];
                SpawnPacket.CopyTo(tmp, 0);

                SpawnPacket = new Byte[tmp.Length + Name.Length + value.Length];
                Buffer.BlockCopy(tmp, 0, SpawnPacket, 0, tmp.Length);

                PacketConstructor.Write((UInt16)SpawnPacket.Length, 0, SpawnPacket);

                PacketConstructor.Write(value, 221 + SpawnPacket[219], SpawnPacket);
            }
        }
    }

    [Flags]
    public enum StatusFlags2 : ulong
    {
        None = 0x00,
        WeeklyTop8Pk = 0x01,
        WeeklyTop2PkGold = 0x2,
        WeeklyTop2PkBlue = 0x4,
        MonthlyTop8Pk = 0x8,
        MontlyTop2Pk = 0x10,
        MontlyTop3Pk = 0x20,
        Top8Fire = 0x40,
        Top2Fire = 0x80,
        Top3Fire = 0x100,
        Top8Water = 0x200,
        Top2Water = 0x400,
        Top3Water = 0x800,
        Top8Ninja = 0x1000,
        Top2Ninja = 0x2000,
        Top3Ninja = 0x4000,
        Top8Warrior = 0x8000,
        Top2Warrior = 0x10000,
        Top3Warrior = 0x20000,
        Top8Trojan = 0x40000,
        Top2Trojan = 0x80000,
        Top3Trojan = 0x100000,
        Top8Archer = 0x200000,
        Top2Archer = 0x400000,
        Top3Archer = 0x800000,
        Top3SpouseBlue = 0x1000000,
        Top2SpouseBlue = 0x2000000,
        Top3SpouseYellow = 0x4000000,
        Contestant = 0x8000000,
        ChainBoltActive = 0x10000000,
        AzureShield = 0x20000000,
        AzureShieldFade = 0x40000000,
        CaryingFlag = 0x80000000,
        TyrantAura = 0x400000000,
        FendAura = 0x1000000000,
        MetalAura = 0x4000000000,
        WoodAura = 0x10000000000,
        WaterAura = 0x40000000000,
        FireAura = 0x100000000000,
        EarthAura = 0x400000000000,
        Shackled = 0x800000000000,
        Oblivion = 0x1000000000000,
        TopMonk = 0x4000000000000,
        Top8Monk = 0x8000000000000,
        Top2Monk = 0x10000000000000,
        Top3Monk = 0x20000000000000
    }

    [Flags]
    public enum StatusFlags : ulong
    {
        None = 0x00,
        BlueName = 0x01,
        Poisoned = 0x02,
        XPSkills = 0x10,
        Ghost = 0x20,
        TeamLeader = 0x40,
        Accuracy = 0x80,
        Shield = 0x100,
        Stigma = 0x200,
        Dead = 0x400,
        FadeAway = 0x800,
        RedName = 0x4000,
        BlackName = 0x8000,
        Superman = 0x40000,
        Invisible = 0x80000,
        InvisibleFully = 0x400000,
        Cyclone = 0x800000,
        Dodge = 0x4000000,
        Fly = 0x8000000,
        Intensify = 0x10000000,
        Stop = 0x20000000,
        CastPray = 0x40000000,
        Praying = 0x80000000,
        Cursed = 0x100000000,
        TopGuildLeader = 0x400000000,
        TopDeputyLeader = 0x800000000,
        MonthlyPKChampion = 0x1000000000,
        WeeklyPKChampion = 0x2000000000,
        TopWarrior = 0x4000000000,
        TopTrojan = 0x8000000000,
        TopArcher = 0x10000000000,
        TopWaterTaoist = 0x20000000000,
        TopFireTaoist = 0x40000000000,
        TopNinja = 0x80000000000,
        ShurikenVortex = 0x400000000000,
        FatalStrike = 0x800000000000,
        Flashy = 0x1000000000000,
        Ride = 0x4000000000000,
        TopSpouse = 0x8000000000000,
        Sparkly = 0x10000000000000,
        SparklyDark = 0x20000000000000,
        Stunned = 0x40000000000000,
        SparklyReborn = 0x80000000000000,
        MoveSpeedRecovered = 0x100000000000000,
        SuperShieldHalo = 0x200000000000000,
        Dazed = 0x400000000000000,
        Frozen = 0x800000000000000,
        Disoriented = 0x1000000000000000
    }
}
